package com.fishingwithme.infrastructure;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户名密码登录过滤器
 * 处理用户名密码登录请求
 */
public class UsernamePasswordLoginFilter extends AbstractAuthenticationProcessingFilter {

    public UsernamePasswordLoginFilter() {
        super(new AntPathRequestMatcher("/user/login", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException {
        
        // 使用ObjectMapper解析JSON请求
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, String> requestParams = objectMapper.readValue(request.getInputStream(), Map.class);
        
        if (requestParams == null) {
            requestParams = new HashMap<>();
        }

        // 获取用户名和密码
        String username = requestParams.getOrDefault("username", "").trim();
        String password = requestParams.getOrDefault("password", "").trim();

        // 参数验证
        if (username.isEmpty() || password.isEmpty()) {
            throw new org.springframework.security.authentication.BadCredentialsException("用户名或密码不能为空");
        }

        // 创建认证Token
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
        setDetails(request, authRequest);

        // 执行认证
        return getAuthenticationManager().authenticate(authRequest);
    }

    private void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
}